package net.gazhi.delonix.grac.init;

import java.util.ArrayList;
import java.util.List;

import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtMethod;
import net.gazhi.delonix.core.dao.Dao;
import net.gazhi.delonix.core.init.InitService;
import net.gazhi.delonix.grac.AC_TB;
import net.gazhi.delonix.grac.entity.act.Action;
import net.gazhi.delonix.grac.entity.act.Controller;
import net.gazhi.delonix.grac.entity.act.Module;
import net.gazhi.delonix.grac.service.ActionService;
import net.gazhi.delonix.grac.web.annonation.Handler;
import net.gazhi.delonix.grac.web.annonation.SortedControllers;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 初始化 Module / Controller / Action
 * 
 * @author Jeffrey Lin
 */
public class InitActionService implements InitService {

	private static final Log logger = LogFactory.getLog(InitActionService.class);

	@Autowired
	private Dao dao;

	private String[] sortedPackages;

	public void setSortedPackages(String[] sortedPackages) {
		this.sortedPackages = sortedPackages;
	}

	@Override
	public void init() throws Exception {
		logger.info("正在初始化 [Action]...");

		dao.createSQLQuery("truncate table " + AC_TB.ac_action).executeUpdate();
		dao.createSQLQuery("truncate table " + AC_TB.ac_controller).executeUpdate();
		dao.createSQLQuery("truncate table " + AC_TB.ac_module).executeUpdate();

		long moduleId = 0;
		long controllerId = 0;
		List<Module> modules = new ArrayList<Module>();
		List<Controller> controllers = new ArrayList<Controller>();
		List<Action> actions = new ArrayList<Action>();
		ClassPool pool = ClassPool.getDefault();
		pool.insertClassPath(new ClassClassPath(this.getClass()));
		for (String pkgName : sortedPackages) {

			// 根据 Package 创建 Module
			Package pkg = Package.getPackage(pkgName);
			Handler pkgHandler = pkg.getAnnotation(Handler.class);
			Module module = new Module(++moduleId, pkgHandler.zh(), pkgHandler.en(), pkgName);
			modules.add(module);

			for (Class<?> clazz : pkg.getAnnotation(SortedControllers.class).value()) {

				// 根据 Class 创建 Controller
				Handler clsHander = clazz.getAnnotation(Handler.class);
				Controller controller = new Controller(++controllerId, clsHander.zh(), clsHander.en(), clazz.getSimpleName(), module);
				controllers.add(controller);

				for (CtMethod ctMethod : pool.get(clazz.getName()).getMethods()) {

					// 根据 CtMethod 创建 Action
					Handler handler = (Handler) ctMethod.getAnnotation(Handler.class);
					if (handler == null) {
						continue;
					}

					// 取行号作为 showOrder
					int showOrder = ctMethod.getMethodInfo().getLineNumber(0);
					// 取 className.methodName 的 HashCode 绝对值作为 actionId,
					// 执行初始化不影响原有的权限配置
					long actionId = ActionService.generateActionId(clazz.getName() + "." + ctMethod.getName());
					Action action = new Action(actionId, handler.zh(), handler.en(), ctMethod.getName(), showOrder, controller);
					actions.add(action);
				}
			}
		}
		dao.saveAll(modules);
		dao.saveAll(controllers);
		dao.saveAll(actions);
		dao.flushSession();

		logger.info("初始化 [Action] 完成。");
	}

}
